package com.cn;
import com.cn.pb.BasePb.Base;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.buffer.PooledByteBufAllocator;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;

public class Net implements Runnable {
	private ServerBootstrap bootstrap = new ServerBootstrap();
	private EventLoopGroup bossGroup = new NioEventLoopGroup();
	private EventLoopGroup workerGroup = new NioEventLoopGroup();

//	private GlobalTrafficShapingHandler trafficHandler = new GlobalTrafficShapingHandler(workerGroup, 5000L);
	private String ip;
	private int port;
	private String name;
	
	protected Net(String name) {
		this.name = name;
	}

	public void init(String ip, int port) {
		this.ip = ip;
		this.port = port;
		// 定义两个工作线程 bossGroup workerGroup 用于管理channel连接
		bootstrap.group(bossGroup, workerGroup);
		bootstrap.channel(NioServerSocketChannel.class);
		
		bootstrap.option(ChannelOption.SO_BACKLOG, 1024);
		// 通过NoDelay禁用Nagle,使消息立即发出去，不用等待到一定的数据量才发出去
		bootstrap.option(ChannelOption.TCP_NODELAY, true);
		bootstrap.option(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT);
		
		bootstrap.childHandler(new ChannelInitHandler(new ChannelIoHandler(this)));
		
		bootstrap.childOption(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT);
		bootstrap.childOption(ChannelOption.SO_KEEPALIVE, true);
		bootstrap.childOption(ChannelOption.SO_REUSEADDR, true);
	}

	public void start() {
		new Thread(this).start();
	}

	public void stop() {
		bossGroup.shutdownGracefully();
		workerGroup.shutdownGracefully();
	}

	private void bind() {
		ChannelFuture f;
		try {
			LogHelper.GAME_LOGGER.info(name + " 开始绑定端口-->" + ip + ":" + port);
			// 绑定端口，同步等待成功
			f = bootstrap.bind(port).sync();
			LogHelper.GAME_LOGGER.info(name + " 绑定端口成功!");
			f.channel().closeFuture().sync();
		} catch (InterruptedException e) {
			e.printStackTrace();
			LogHelper.GAME_LOGGER.error(name + " 服务器网络初始化异常", e);
		}
	}

	public void run() {
		bind();
	}

}
